/**
 * API服务类 - 展示前端如何使用JavaScript高级特性
 * 对应后端Python的生成器、迭代器、装饰器等特性
 */

// 装饰器：API请求拦截器
function apiLogger(target, name, descriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = async function(...args) {
    const startTime = performance.now();
    console.log(`[API请求] ${name} 开始`, ...args);

    try {
      const result = await originalMethod.apply(this, args);
      const endTime = performance.now();
      console.log(`[API请求] ${name} 完成，耗时: ${(endTime - startTime).toFixed(2)}ms`);
      return result;
    } catch (error) {
      const endTime = performance.now();
      console.error(`[API请求] ${name} 失败，耗时: ${(endTime - startTime).toFixed(2)}ms`, error);
      throw error;
    }
  };

  return descriptor;
}

// 装饰器：缓存API结果
const apiCache = new Map();

function cacheApiResult(expiryMs = 5 * 60 * 1000) { // 默认5分钟缓存
  return function(target, name, descriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = async function(...args) {
      const cacheKey = `${name}:${JSON.stringify(args)}`;

      // 检查缓存
      if (apiCache.has(cacheKey)) {
        const { timestamp, result } = apiCache.get(cacheKey);
        if (Date.now() - timestamp < expiryMs) {
          console.log(`[API缓存] 使用缓存结果: ${cacheKey}`);
          return result;
        } else {
          // 缓存过期，删除
          apiCache.delete(cacheKey);
        }
      }

      // 执行API请求
      const result = await originalMethod.apply(this, args);

      // 缓存结果
      apiCache.set(cacheKey, {
        timestamp: Date.now(),
        result: result
      });

      return result;
    };

    return descriptor;
  };
}

// 装饰器：重试机制
function retryApi(maxRetries = 3, delayMs = 1000) {
  return function(target, name, descriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = async function(...args) {
      let lastError;

      for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
          return await originalMethod.apply(this, args);
        } catch (error) {
          lastError = error;
          console.warn(`[API重试] 第${attempt}次尝试失败:`, error.message);

          if (attempt < maxRetries) {
            await new Promise(resolve => setTimeout(resolve, delayMs * attempt));
          }
        }
      }

      throw lastError;
    };

    return descriptor;
  };
}

class ApiService {
  constructor(baseURL = 'http://127.0.0.1:8000') {
    this.baseURL = baseURL;
    this.token = localStorage.getItem('access_token');
  }

  // 设置认证token
  setToken(token) {
    this.token = token;
    localStorage.setItem('access_token', token);
  }

  // 获取认证头
  getAuthHeaders() {
    return this.token ? {
      'Authorization': `Bearer ${this.token}`,
      'Content-Type': 'application/json'
    } : {
      'Content-Type': 'application/json'
    };
  }

  // 异步生成器：逐个处理API响应数据
  async* processApiDataGenerator(endpoint, params = {}) {
    try {
      const queryString = new URLSearchParams(params).toString();
      const url = `${this.baseURL}${endpoint}${queryString ? '?' + queryString : ''}`;

      console.log('[生成器] 开始处理API数据:', url);

      // 模拟分批获取数据
      for (let page = 1; page <= 3; page++) {
        const response = await fetch(`${url}&page=${page}&page_size=5`, {
          headers: this.getAuthHeaders()
        });

        if (!response.ok) {
          throw new Error(`API请求失败: ${response.status}`);
        }

        const data = await response.json();
        console.log(`[生成器] 处理第${page}页数据:`, data);

        // yield返回数据，供外部迭代
        yield {
          page,
          data: data.cards || [],
          hasNext: data.has_next || false
        };

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 500));
      }
    } catch (error) {
      console.error('[生成器] 处理失败:', error);
      throw error;
    }
  }

  // 异步迭代器：过滤API数据
  async* filterApiData(dataGenerator, filterFn) {
    for await (const batch of dataGenerator) {
      const filteredData = batch.data.filter(filterFn);
      console.log(`[迭代器] 过滤后数据:`, filteredData);

      if (filteredData.length > 0) {
        yield {
          ...batch,
          data: filteredData
        };
      }
    }
  }

  // 静态方法：创建API实例
  static create(baseURL) {
    return new ApiService(baseURL);
  }

  // 静态方法：格式化错误信息
  static formatError(error) {
    if (error.response) {
      return `服务器错误: ${error.response.status} - ${error.response.statusText}`;
    } else if (error.request) {
      return '网络请求失败，请检查网络连接';
    } else {
      return error.message || '未知错误';
    }
  }

  // 获取卡片列表 - 演示装饰器和生成器
  @cacheApiResult(30000) // 30秒缓存
  @retryApi(2) // 最多重试2次
  @apiLogger
  async getCards(category = null, page = 1, pageSize = 10) {
    const params = {
      page,
      page_size: pageSize,
      ...(category && { category })
    };

    const response = await fetch(`${this.baseURL}/api/v1/cards`, {
      method: 'GET',
      headers: this.getAuthHeaders(),
      params
    });

    if (!response.ok) {
      throw new Error(`获取卡片失败: ${response.status}`);
    }

    return await response.json();
  }

  // 使用生成器获取卡片数据
  @apiLogger
  async getCardsWithGenerator(category = null) {
    const dataGenerator = this.processApiDataGenerator('/api/v1/cards', { category });
    const allCards = [];

    // 异步迭代处理数据
    for await (const batch of dataGenerator) {
      allCards.push(...batch.data);

      if (!batch.hasNext) {
        break;
      }
    }

    console.log('[生成器] 总共获取到卡片:', allCards.length);
    return allCards;
  }

  // 使用迭代器过滤卡片
  @apiLogger
  async getFilteredCards(filterFn, category = null) {
    const dataGenerator = this.processApiDataGenerator('/api/v1/cards', { category });
    const filteredGenerator = this.filterApiData(dataGenerator, filterFn);
    const filteredCards = [];

    for await (const batch of filteredGenerator) {
      filteredCards.push(...batch.data);
    }

    console.log('[迭代器] 过滤后卡片数量:', filteredCards.length);
    return filteredCards;
  }

  // 用户登录
  @retryApi(2)
  @apiLogger
  async login(username, password) {
    const response = await fetch(`${this.baseURL}/auth/login`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ username, password })
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.detail || '登录失败');
    }

    const data = await response.json();
    this.setToken(data.access_token);
    return data;
  }

  // 用户注册
  @retryApi(2)
  @apiLogger
  async register(userData) {
    const response = await fetch(`${this.baseURL}/auth/register`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userData)
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.detail || '注册失败');
    }

    return await response.json();
  }

  // 获取用户资料
  @cacheApiResult(60000) // 1分钟缓存
  @retryApi(2)
  @apiLogger
  async getProfile(userId) {
    const response = await fetch(`${this.baseURL}/auth/profile?user_id=${userId}`, {
      headers: this.getAuthHeaders()
    });

    if (!response.ok) {
      throw new Error(`获取用户资料失败: ${response.status}`);
    }

    return await response.json();
  }

  // 深拷贝示例 - 克隆对象
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }

    if (obj instanceof Date) {
      return new Date(obj.getTime());
    }

    if (obj instanceof Array) {
      return obj.map(item => this.deepClone(item));
    }

    if (typeof obj === 'object') {
      const cloned = {};
      Object.keys(obj).forEach(key => {
        cloned[key] = this.deepClone(obj[key]);
      });
      return cloned;
    }
  }

  // 浅拷贝示例 - 克隆对象
  shallowClone(obj) {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }

    if (obj instanceof Date) {
      return new Date(obj.getTime());
    }

    if (obj instanceof Array) {
      return [...obj];
    }

    return { ...obj };
  }

  // 演示深浅拷贝
  @apiLogger
  async demonstrateCopy() {
    const originalData = {
      id: 1,
      title: '示例卡片',
      metadata: {
        views: 100,
        likes: 50,
        tags: ['热门', '推荐']
      },
      createdAt: new Date()
    };

    console.log('[深浅拷贝演示] 原始数据:', originalData);

    // 浅拷贝
    const shallowCopy = this.shallowClone(originalData);
    console.log('[浅拷贝] 浅拷贝结果:', shallowCopy);
    console.log('[浅拷贝] 是否相同对象:', shallowCopy === originalData);
    console.log('[浅拷贝] metadata是否相同对象:', shallowCopy.metadata === originalData.metadata);

    // 深拷贝
    const deepCopy = this.deepClone(originalData);
    console.log('[深拷贝] 深拷贝结果:', deepCopy);
    console.log('[深拷贝] 是否相同对象:', deepCopy === originalData);
    console.log('[深拷贝] metadata是否相同对象:', deepCopy.metadata === originalData.metadata);

    // 修改浅拷贝的嵌套对象
    shallowCopy.metadata.views = 200;
    console.log('[修改浅拷贝] 原始数据views:', originalData.metadata.views); // 也会改变
    console.log('[修改浅拷贝] 浅拷贝views:', shallowCopy.metadata.views);

    // 修改深拷贝的嵌套对象
    deepCopy.metadata.likes = 100;
    console.log('[修改深拷贝] 原始数据likes:', originalData.metadata.likes); // 不改变
    console.log('[修改深拷贝] 深拷贝likes:', deepCopy.metadata.likes);

    return {
      original: originalData,
      shallow: shallowCopy,
      deep: deepCopy,
      message: '深拷贝保护了原始数据的完整性'
    };
  }
}

// 创建默认实例
const apiService = new ApiService();

// 导出
export default apiService;
export { ApiService };
